package vek.XML.Parsers;

import org.xml.sax.ContentHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import vek.XML.parsedObjects.ParsedAddresse;
import vek.XML.parsedObjects.ParsedAttractions;
import vek.XML.parsedObjects.ParsedOpeninghours;

/**
 * Parses the POIAttraction part of the XML files from < attractionspoi > to < /attractionspoi >.
 * NOTE: this class inherits from XMLParserPOI and also does everything the XMLParserPOI does.
 * thus the part from < poi> to < /poi> will be parsed by the methods in XMLParserPOI.
 * It does this by calling its supermethod as well has having its own implementation of the startElement and endElement methods
 * This ensures that this class only has to concern itself with parsing the attractionspoi part of the XML file while still retaining behavior from its superclass
 * @author Christian, Michal og Jakob (Hold 1, gruppe 2)
 */
public abstract class XMLParserAttractions extends XMLParserPOI implements ContentHandler {
    
    private boolean parsingAttractionsPOI;
    private boolean parsingContactInformation;
    private boolean parsingDescription;
    private boolean parsingAddress;
    private boolean parsingOpeninghours;
    private boolean parsingFacilities;
    
    //addresse variables
    private String road;
    private int roadNumber;
    private String extraInfo;
    private int postcode;
    private String city;
    private String country;
    private ParsedAddresse parsedAddresse;
    
    private int phonenumber;
    private String email;
    private String url;
    private String showedurl;
    private String description;
    
    //openinghours variables
    private int[] weekStartTimes = new int[7]; //sunday == weekStartTimes[0]
    private int[] weekEndTimes = new int[7]; //sunday == weekEndTimes[0]
    private ParsedOpeninghours parsedOpeninghours;
    
    //facilities
    private boolean toilets;
    private boolean elevators;
    private boolean handicapfriendly;
    
    protected ParsedAttractions parsedAttraction;
    
    @Override
    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
        
        super.startElement(uri, localName, qName, atts);
        
        if(localName.equals("attractionspoi"))
            {
                parsingAttractionsPOI = true;
            }  
        
        if(parsingAttractionsPOI)
        {
            setTopElementStartTagsAttractions(uri, localName, qName, atts);            
        }
        
    }
    
    private void setTopElementEndTagsAttractions(String uri, String localName, String qName) throws SAXException 
    {
        if(localName.equals("contactinformation"))
        {
            parsingContactInformation = false;
        }               
        else if(localName.equals("address"))
        {
            parsingAddress = false;
        }
        else if(localName.equals("openinghours"))
        {
            parsingOpeninghours = false;
        }
        else if(localName.equals("facilities"))
        {
            parsingFacilities = false;
        }
        else if(localName.equals("description"))
        {
            parsingDescription = false;
        }
    }
    
    private void setTopElementStartTagsAttractions(String uri, String localName, String qName, Attributes atts) throws SAXException
    {
        if(localName.equals("contactinformation"))
            {
                parsingContactInformation = true;
            }               
            else if(localName.equals("address"))
            {
                parsingAddress = true;
            }
            else if(localName.equals("openinghours"))
            {
                parsingOpeninghours = true;
            }
            else if(localName.equals("facilities"))
            {
                parsingFacilities = true;
            }
            else if(localName.equals("description"))
            {
                parsingDescription = true;
            }     
    }
    

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        
        super.endElement(uri, localName, qName);
        
        if(localName.equals("attractionspoi"))
        {
            parsingAttractionsPOI = false;
            parsedAttraction = new ParsedAttractions(parsedPOI, parsedAddresse, 
                    phonenumber, url, showedurl, email, parsedOpeninghours, 
                    description, toilets, elevators, handicapfriendly);
        }
        if(parsingAttractionsPOI)
        {
            
            if(parsingAddress)
            {
                parseAdresse(uri, localName, qName);
            }
            else if(parsingContactInformation)
            {
                parseContactInformation(uri, localName, qName);
            }
            else if(parsingOpeninghours)
            {
                parseOpeninghours(uri, localName, qName);
            }
            else if(parsingDescription)
            {
                parseDescription(uri, localName, qName);
            }
            else if(parsingFacilities)
            {
                parseFacilities(uri, localName, qName);
            }
            
            setTopElementEndTagsAttractions(uri, localName, qName);
        }

        
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        
       tempElementData = new String(ch, start, length);    
    }
    
    /**
     * Parses the description part of the XML
     * @param uri not used
     * @param localName the name of the tag
     * @param qName not used
     */
    
    private void parseDescription(String uri, String localName, String qName)
    {
        if(localName.equals("description"))
        {
            description = tempElementData;
        }
    }
    
    /**
     * Parses the contact information part of the XML file, saves the information in  variables
     * @param uri
     * @param localName the name of the tag
     * @param qName
     */
    
    private void parseContactInformation(String uri, String localName, String qName)
    {
        if(parsingAddress)
        {
            parseAdresse(uri, localName, qName);
        }
        else if(localName.equals("phonenumber"))
        {
            phonenumber = Integer.parseInt(tempElementData);
        }
        else if(localName.equals("emailaddress"))
        {
            email = tempElementData;
        }
        else if(localName.equals("url"))
        {
            url = tempElementData;
        }
        else if(localName.equals("showedurl"))
        {
            showedurl = tempElementData;
        }
        
    }
    
    /**
     * Parses the Addresse part of the XML, saves the information by instantiating a new ParsedAddresse.
     * @param uri not used
     * @param localName the name of the tag
     * @param qName not used
     */
    
    private void parseAdresse(String uri, String localName, String qName)
    {
        if(localName.equals("road"))
        {
            road = tempElementData;
        }
        else if(localName.equals("roadnumber"))
        {
            roadNumber = Integer.parseInt(tempElementData);
        }  
        else if(localName.equals("extraadresseinfo"))
        {
            extraInfo = tempElementData;
        }
        else if(localName.equals("postcode"))
        {
            postcode = Integer.parseInt(tempElementData);
        }
        else if(localName.equals("city"))
        {
            city = tempElementData;
        }
        else if(localName.equals("country"))
        {
            country = tempElementData;
        }
        else if(localName.equals("address"))
        {
            parsedAddresse = new ParsedAddresse(road, roadNumber, extraInfo, postcode, city, country);
        }
        
    }
    
    /**
     * Checks if the data inside a tag equals "closed"
     * @param weekday the weekday, not currently used
     * @return true if the tempElementData variable equals closed (not case sensitive)
     */
    
    private boolean checkIfClosed(int weekday)
            {
        boolean isClosed = false;
            if(tempElementData.equalsIgnoreCase("closed"))
                {
                isClosed = true;
                }
            return isClosed;
            }
    
    /**
     * sets the opening hours of the given weekday to -1, meaning that it's closed.
     * @param weekday the day of the week which is closed (0 == sunday, 6 == saturday)
     */
    
    private void setStartAndEndTimesToClosed(int weekday)
    {
        weekStartTimes[weekday] = -1;
        weekEndTimes[weekday] = -1;
    }
    
    /**
     * converts a weekday in string format to the int format used for weekdays.
     * monday == 0, saturday == 6
     * @param weekdayString
     * @return the week day as an int
     */
    
    private int weekdayToInt(String weekdayString)
        {
        int weekdayInt = -1;
        if(weekdayString.equalsIgnoreCase("monday"))
        {
            weekdayInt = 1;
        }
        else if(weekdayString.equalsIgnoreCase("tuesday"))
        {
            weekdayInt = 2;
        }
        else if(weekdayString.equalsIgnoreCase("wednesday"))
        {
            weekdayInt = 3;
        }
        else if(weekdayString.equalsIgnoreCase("thursday"))
        {
            weekdayInt = 4;
        }
        else if(weekdayString.equals("friday"))
        {
            weekdayInt = 5;
        }
        else if(weekdayString.equals("saturday"))
        {
            weekdayInt = 6;
        }
        else if(weekdayString.equals("sunday"))
        {
            weekdayInt = 0;
        }
        assert weekdayInt != -1 : "ERROR: weekday == -1";
        return weekdayInt;
        }
    
    /**
     * parses the opening hours of a POI
     * @param uri not used
     * @param localName the name of the tag
     * @param qName not used
     */
    
    private void parseOpeninghours(String uri, String localName, String qName)
    {
    //    weekdayToInt(localName);
        if(localName.equals("monday"))
        {
                int weekday = weekdayToInt(localName);
                if(checkIfClosed(weekday) == true)
                {
                    setStartAndEndTimesToClosed(weekday);
                }
                if(checkIfClosed(weekday) == false)
                {
                    String startTime = tempElementData.substring(0, 4);
                    String endTime = tempElementData.substring(5, 9);
                    weekStartTimes[weekday] = Integer.parseInt(startTime);
                    weekEndTimes[weekday] = Integer.parseInt(endTime);
                }
        }
        else if(localName.equals("tuesday"))
        {
            int weekday = weekdayToInt(localName);
            if(checkIfClosed(weekday) == true)
            {
                setStartAndEndTimesToClosed(weekday);
            }
            if(checkIfClosed(weekday) == false)
            {
                String startTime = tempElementData.substring(0, 4);
                String endTime = tempElementData.substring(5, 9);
                weekStartTimes[weekday] = Integer.parseInt(startTime);
                weekEndTimes[weekday] = Integer.parseInt(endTime);
            }   
        }
        else if(localName.equals("wednesday"))
        {
            int weekday = weekdayToInt(localName);
            if(checkIfClosed(weekday) == true)
            {
                setStartAndEndTimesToClosed(weekday);
            }
           if(checkIfClosed(weekday) == false)
            {
                String startTime = tempElementData.substring(0, 4);
                String endTime = tempElementData.substring(5, 9);
                weekStartTimes[weekday] = Integer.parseInt(startTime);
                weekEndTimes[weekday] = Integer.parseInt(endTime);
            }
        }
        else if(localName.equals("thursday"))
        {
            int weekday = weekdayToInt(localName);
            if(checkIfClosed(weekday) == true)
            {
                setStartAndEndTimesToClosed(weekday);
            }
           if(checkIfClosed(weekday) == false)
            {
                String startTime = tempElementData.substring(0, 4);
                String endTime = tempElementData.substring(5, 9);
                weekStartTimes[weekday] = Integer.parseInt(startTime);
                weekEndTimes[weekday] = Integer.parseInt(endTime);
            }
        }
        else if(localName.equals("friday"))
        {
            int weekday = weekdayToInt(localName);
            if(checkIfClosed(weekday) == true)
            {
                setStartAndEndTimesToClosed(weekday);
            }
           if(checkIfClosed(weekday) == false)
            {
                String startTime = tempElementData.substring(0, 4);
                String endTime = tempElementData.substring(5, 9);
                weekStartTimes[weekday] = Integer.parseInt(startTime);
                weekEndTimes[weekday] = Integer.parseInt(endTime);
            }
        }
        else if(localName.equals("saturday"))
        {
            int weekday = weekdayToInt(localName);
            if(checkIfClosed(weekday) == true)
            {
                setStartAndEndTimesToClosed(weekday);
            }
           if(checkIfClosed(weekday) == false)
            {
                String startTime = tempElementData.substring(0, 4);
                String endTime = tempElementData.substring(5, 9);
                weekStartTimes[weekday] = Integer.parseInt(startTime);
                weekEndTimes[weekday] = Integer.parseInt(endTime);
            }
        }
        else if(localName.equals("sunday"))
        {
            int weekday = weekdayToInt(localName);
            if(checkIfClosed(weekday) == true)
            {
                setStartAndEndTimesToClosed(weekday);
            }
           if(checkIfClosed(weekday) == false)
            {
                String startTime = tempElementData.substring(0, 4);
                String endTime = tempElementData.substring(5, 9);
                weekStartTimes[weekday] = Integer.parseInt(startTime);
                weekEndTimes[weekday] = Integer.parseInt(endTime);
            }
        }
        
        else if(localName.equals("openinghours"))
        {
            parsedOpeninghours = new ParsedOpeninghours(weekStartTimes, weekEndTimes);
            parsingOpeninghours = false;
        } 
    }
    
    /**
     * Parses the facilities part of the poi (toilets, elevators and handicap friendly)
     * @param uri not used
     * @param localName the name of the tag
     * @param qName not used
     */
    
    private void parseFacilities(String uri, String localName, String qName)
    {
        if(localName.equals("toilets"))
        {
            toilets = Boolean.parseBoolean(tempElementData);
        }
        else if(localName.equals("elevators"))
        {
            elevators = Boolean.parseBoolean(tempElementData);
        }
        else if(localName.equals("handicapfriendly"))
        {
            handicapfriendly = Boolean.parseBoolean(tempElementData);
        }
        else if(localName.equals("facilities"))
        {
            parsingFacilities = false;
        }
        
    }
    
    

}

